package cn.jx.cjm.security.common.filter;

import cn.jx.cjm.common.contants.CommonCache;
import cn.jx.cjm.common.enums.BizExceptionEnum;
import cn.jx.cjm.common.util.JwtTokenUtils;
import cn.jx.cjm.security.common.bean.CjmDepartment;
import cn.jx.cjm.security.common.bean.TokenUser;
import cn.jx.cjm.security.common.config.UserTokenProperties;
import cn.jx.cjm.security.common.constant.SecuritySystemConstants;
import cn.jx.cjm.security.common.util.ResponseUtils;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.api.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.NonNull;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.stream.Collectors;

/**
 * 通过Token从Redis缓存中获取用户信息
 *
 * @author 陈加敏
 * @since 2019/7/15 13:56
 */
@Slf4j
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    @Autowired
    private UserTokenProperties userTokenProperties;
    @Autowired
    private ResponseUtils responseUtils;


    @Override
    protected void doFilterInternal(HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull FilterChain chain)
            throws ServletException, IOException {
        //初始化请求头

        if (SecuritySystemConstants.OPTIONS.equals(request.getMethod().toUpperCase())) {
            responseUtils.send(request, response, JSON.toJSONString(R.failed(BizExceptionEnum.AUTH_ERROR)));
            return;
        }
        //获取请求token
        String authToken = request.getHeader(userTokenProperties.getTokenHeader());
        if (!StringUtils.isEmpty(authToken)) {
            TokenUser tokenUser = JwtTokenUtils.parse(authToken, TokenUser.class);
            if (null != tokenUser) {
                if (SecurityContextHolder.getContext().getAuthentication() == null) {
                    UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
                            tokenUser,
                            tokenUser.getPassword(),
                            tokenUser.getAuthorities());
                    authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                    SecurityContextHolder.getContext().setAuthentication(authentication);
                }
                CommonCache.departmentIds.set(tokenUser.getDepartments().stream().map(CjmDepartment::getDepartmentRule).collect(Collectors.toList()));
            } else {
                //向前端发送错误信息
                responseUtils.send(request, response, JSON.toJSONString(R.failed(BizExceptionEnum.AUTH_ERROR)));
                return;
            }
        }
        chain.doFilter(request, response);
    }
}
